package com.zmc.lostfound.auth.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zmc.lostfound.auth.dao.PermissionDao;
import com.zmc.lostfound.auth.entity.PermissionEntity;
import com.zmc.lostfound.auth.entity.RolePermissionEntity;
import com.zmc.lostfound.auth.service.PermissionService;
import com.zmc.lostfound.auth.service.RolePermissionService;
import com.zmc.lostfound.auth.vo.PermissionOfRoleVO;
import com.zmc.lostfound.auth.vo.PermissionSaveVO;
import com.zmc.lostfound.common.exception.MyException;
import com.zmc.lostfound.common.utils.PageParams;
import com.zmc.lostfound.common.utils.PageResult;
import com.zmc.lostfound.common.utils.Result;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author ZMC
 * @description 权限菜单管理业务接口
 * @email 2869581855@qq.com
 * @date 2023-07-05 15:17:37
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionDao, PermissionEntity> implements PermissionService {

    private final RolePermissionService rolePermissionService;

    public PermissionServiceImpl(RolePermissionService rolePermissionService) {
        this.rolePermissionService = rolePermissionService;
    }

    /**
     * 分页模糊查询权限信息
     *
     * @param pageParams 分页查询参数
     * @return PageResult
     */
    @Override
    public PageResult queryPage(PageParams pageParams) {
        Integer pageNo = pageParams.getPageNo();
        Integer pageSize = pageParams.getPageSize();
        String keyword = pageParams.getKeyword();
        Page<PermissionEntity> page = new Page<>(pageNo, pageSize);
        QueryWrapper<PermissionEntity> queryWrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(keyword)) {
            queryWrapper.eq("id", keyword)
                    .or()
                    .eq("permission_code", keyword)
                    .or()
                    .like("permission_name", keyword)
                    .or()
                    .like("permission_code", keyword)
                    .or()
                    .like("server_name", keyword);
        }
        return new PageResult(this.page(page, queryWrapper));
    }

    /**
     * 按id查询权限信息
     *
     * @param id 权限id
     * @return PermissionEntity
     */
    @Override
    public PermissionEntity queryInfoById(Long id) {
        if (id == null || id <= 0) {
            MyException.throwException("查询失败: 权限id不能为null且必须大于0");
        }
        return this.getById(id);
    }

    /**
     * 按用户id查询权限信息
     *
     * @param userId 用户id
     * @return List<PermissionEntity>
     */
    @Override
    public List<PermissionEntity> queryInfoByUserId(Long userId) {
        if (userId == null || userId <= 0) {
            MyException.throwException("查询失败: 用户id不能为null且必须大于0");
        }
        return this.baseMapper.queryInfoByUserId(userId);
    }

    /**
     * 按角色id查询所拥有权限信息
     *
     * @param roleId 角色id
     * @return List<PermissionEntity>
     */
    @Override
    public List<PermissionEntity> queryInfoByRoleId(Long roleId) {
        if (roleId == null || roleId <= 0) {
            MyException.throwException("查询失败: 角色id不能为null且必须大于0");
        }
        return this.baseMapper.queryInfoByRoleId(roleId);
    }

    /**
     * 按角色id查询所有权限信息
     *
     * @param roleId     角色id
     * @param pageParams 分页参数
     * @return PageResult
     */
    @Override
    public PageResult queryInfoByRoleIdWithAll(Long roleId, PageParams pageParams) {
        if (roleId == null || roleId <= 0) {
            MyException.throwException("查询失败: 角色id不能为null且必须大于0");
        }
        Integer pageNo = pageParams.getPageNo();
        Integer pageSize = pageParams.getPageSize();
        // 1.查询角色拥有的权限ids
        List<RolePermissionEntity> list = rolePermissionService.query().select("permission_id").eq("role_id", roleId).list();
        List<Long> permissionIds = list.stream().map(RolePermissionEntity::getPermissionId).collect(Collectors.toList());
        // 2.查询所有权限信息
        List<PermissionEntity> permissionList = this.list();
        List<PermissionOfRoleVO> permissionOfRoleVOList = permissionList.stream()
                .map(permissionEntity -> BeanUtil.copyProperties(permissionEntity, PermissionOfRoleVO.class))
                .collect(Collectors.toList());
        // 3.设置权限是否属于该角色的标志，并按照HasPermission降序排序(true 在前，false 在后)
        permissionOfRoleVOList.forEach(permissionOfRoleVO -> {
            permissionOfRoleVO.setRoleId(roleId);
            permissionOfRoleVO.setHasPermission(permissionIds.contains(permissionOfRoleVO.getId()));
        });
        permissionOfRoleVOList.sort((p1, p2) -> {
            if (p1.getHasPermission() ^ p2.getHasPermission()) {
                return p1.getHasPermission() ? -1 : 1;
            } else {
                return 0;
            }
        });
        // 4.分页
        List<PermissionOfRoleVO> collect = permissionOfRoleVOList.stream()
                .skip((pageNo - 1) * pageSize)
                .limit(pageSize)
                .collect(Collectors.toList());
        return new PageResult(collect, pageNo, pageSize, permissionOfRoleVOList.size());
    }

    /**
     * 新增权限信息
     *
     * @param permissionSaveVO 权限菜单新增/修改请求体
     * @return Result
     */
    @Transactional(rollbackFor = {Exception.class})
    @Override
    public Result insertPermission(PermissionSaveVO permissionSaveVO) {
        PermissionEntity permissionEntity = BeanUtil.copyProperties(permissionSaveVO, PermissionEntity.class);
        if (!this.save(permissionEntity)) {
            MyException.throwException("新增权限信息失败");
        }
        return Result.ok("新增成功");
    }

    /**
     * 修改权限信息
     *
     * @param permissionSaveVO 权限菜单新增/修改请求体
     * @return Result
     */
    @Transactional(rollbackFor = {Exception.class})
    @Override
    public Result updatePermission(PermissionSaveVO permissionSaveVO) {
        PermissionEntity permissionEntity = BeanUtil.copyProperties(permissionSaveVO, PermissionEntity.class);
        if (!this.updateById(permissionEntity)) {
            MyException.throwException("修改权限信息失败");
        }
        return Result.ok("修改成功");
    }

    /**
     * 按权限id删除权限信息
     *
     * @param permissionId 权限id
     * @return Result
     */
    @Transactional(rollbackFor = {Exception.class})
    @Override
    public Result deleteByPermissionId(Long permissionId) {
        if (permissionId == null || permissionId <= 0) {
            MyException.throwException("删除失败: 权限id不能为null且必须大于0");
        }
        // 1.按权限id删除角色&权限关联信息
        rolePermissionService.deleteByRoleIdAndPermissionId(null, permissionId);
        // 3.删除该权限信息
        this.removeById(permissionId);
        return Result.ok("删除成功");
    }

}